:- module(db_update,[
	db_update/3,
	db_recover/2,
	db_resource_check/1,
	gen_ditem/3,
	ditems2terms/3,
	build_ditem/5,
	ditem_current_fact/1,
	ditem_current_fact_entry/1,
	ditem_clone/2,
	ditem_delete_all/1,
	controlled_ditem_db_update/3,
	gen_ditem_list/3],[assertions]).

:- comment(title, "New Resource Insertion into AMOS Database").
:- comment(subtitle, "AMOS Project").

:- comment(author, "Manuel Carro, Jos@'{e} Manuel G@'{o}mez, Jes@'{u}s Correas, and the CLIP Group").
:- comment(author, "Facultad de Inform@'{a}tica").
:- comment(author, "Universidad Polit@'{e}cnica de Madrid").
:- comment(author, "@tt{clip@@dia.fi.upm.es}").
:- comment(author, "@tt{http://www.clip.dia.fi.upm.es/}").

:- comment(module, "

New Resource Insertion into AMOS Database

@sp

@include{../Doc/acknowledgements.lpdoc}

@newpage
").

:- use_module('../../DataBase/database_impl').  %% just to avoid module bug.

:- use_module('../../DataBase/database_access').
:- reexport('../../DataBase/database_access').
:- use_module('../../DataBase/asset_access').
:- use_module('../../DataBase/certification_access').
:- use_module('../../DataBase/dictionary_access').
:- reexport('../../DataBase/dictionary_access').
:- use_module('../../DataBase/organization_access').
:- use_module('../../DataBase/resource_access').
:- use_module('../../DataBase/user_access').
:- use_module('../../DataBase/basic_types').
:- use_module(library(lists),[length/2, nth/3,append/3]).
:- use_module(library(terms),[atom_concat/2]).
:- use_module('../../Prototype/utils',[to_lowercase/2]).
:- use_module(library(write),[writeq/1]).

%%------------------------------------------------------------------------

:- pred db_recover(+ResourceKey,-PkgDesc).

db_recover(ResKey,PkgDesc):-
%	writeq('entering db_recover'(ResKey,PkgDesc)),nl,
	resource(Res),
	resource_description(Res,ResKey),
	!,
	PkgDesc = 'Software_Description_Validation'(ResKey,Name,Version,Size,
	  Description,IdentificationTags,Downloadpage,AuthorName,SubmittedbyName,
	  Contact,
	  License,NewVersionOf,Requires,Uses,LanguageName,Homepage,
	  Creationdate,Cost,_Certification,Security,MaintainerName,
	  Submissiondate,Licenseurl,References,Constraints,Freedom,
	  Environment,Signature),
%%%        --- no certification is currently handled --- 
%%%        --- no notes are currently handled --- 
%
	resource_asset(Res,Asset,Res),
	asset_author(Asset,[Author],Asset),
	(null(Author) ->
	 true
	;
	    user_affiliation(Author,OrgAuthor,Author),
	    (null(OrgAuthor) ->
	     true
	    ;
		organization_name(OrgAuthor,AuthorName,OrgAuthor)
	    )
	),
%
	asset_maintained_by(Asset,MaintainerList,Asset),
	( MaintainerList = [] ; null(MaintainerList) ->
	  true
	;
	    %%% only one maintainer is handled!!!!
	    MaintainerList = [Maintainer|_],
	    ( null(Maintainer) ->
	      true
	    ;
		user_affiliation(Maintainer,OrgMaintainer,Maintainer),
		( null(OrgMaintainer) ->
		  true
		;
		    organization_name(OrgMaintainer,MaintainerName,OrgMaintainer)
		)
	    )
	), 
%
	asset_name(Asset,Name,Asset),
	asset_homepage(Asset,Homepage,Asset),
        asset_download_page(Asset,Downloadpage,Asset),
        asset_license(Asset,License,Asset),
        asset_license_URL(Asset,Licenseurl,Asset),
        asset_version(Asset,Version,Asset),
        asset_references(Asset,References,Asset),
        asset_additional_constraints(Asset,Constraints,Asset),
        asset_additional_freedom(Asset,Freedom,Asset),
        asset_description(Asset,Description,Asset),
        asset_creation_date(Asset,Creationdate,Asset),

	asset_submitted_by(Asset,Submittedby,Asset),
	(null(Submittedby) ->
	 true
	;
	    user_affiliation(Submittedby,OrgSubmittedby,Submittedby),
	    (null(OrgSubmittedby) ->
	     true
	    ;
		organization_name(OrgSubmittedby,SubmittedbyName,OrgSubmittedby)
	    )
	),
%
	asset_contact(Asset,Contact,Asset),
%
	asset_submission_date(Asset,Submissiondate,Asset),
        asset_environment(Asset,Environment,Asset),
        asset_cost(Asset,Cost,Asset),
        asset_security_classification(Asset,Security,Asset),
%%%
%%%        --- no certification is currently handled --- 
%%%     asset_certification(Asset,Cert,Asset),
%%%
        asset_package_signature(Asset,Signature,Asset),
%
	resource_identificationTags(Res,IdTags,Res),
	(null(IdTags)->
	 true
	;
	    list_from_ditem_list(IdTags,IdentificationTags)
	),
%
	resource_requires(Res,Reqs,Res),
	(null(Reqs) ->
	 true
	;
	    list_from_ditem_list(Reqs,Requires)
	),
%
	resource_uses(Res,Uses,Res),
	resource_size(Res,Size,Res),
%
	resource_language(Res,Language,Res),
	(null(Language) ->
	 true
	;
	    ditem_entry(Language,LanguageName,Language)
	), 
%
	resource_newVersionOf(Res,NewVersionOf,Res).
%	writeq(db_recover(ResKey,PkgDesc)),nl.
%%%
%%%        --- no notes are currently handled --- 
%%%        resource_notes(Res,_Notes,Res).
%%%

%%------------------------------------------------------------------------

:- pred list_from_ditem_list(+ditem_list,-list)

# "Given a list of ditems, produces the list of atoms with the names
  of the ditems.".

list_from_ditem_list([],[]).
list_from_ditem_list([Ditem|Ditems],[A|As]):-
	functor(Ditem,F,1),
	arg(1,Ditem,Ditem0),
	ditem_entry(Ditem0,A0,Ditem0),
%	A =.. [F,A0],
	atom_concat([F,'(',A0,')'],A),
%
	list_from_ditem_list(Ditems,As).
list_from_ditem_list([Ditem|Ditems],[A|As]):-
	ditem_entry(Ditem,A,Ditem),
	list_from_ditem_list(Ditems,As).

%%------------------------------------------------------------------------

:- pred db_update(+ValData,-Errors,-Key):
        term * term * atm

# "Checks that @var{ValData} contains the information needed to insert
  a new resource into the database. If there is a resource in the
  database with same name as given by @var{ValData}, this predicate
  succeeds unifying @var{Errors} with the atom 'duplicated_name'. If
  the data in @var{ValData} contain any error, this predicate succeeds
  unifying @var{Errors} with a structure with the same name and arity
  as that of first argument, and with an atom describing the error
  message of those fields which are incorrect.".

db_update(PkgDesc,WrongFields,ResKey):-
%	writeq('entering db_update'(PkgDesc,WrongFields,ResKey)),nl,
	PkgDesc = 'Software_Description_Validation'(Key0,Name,_,_,
	  _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_),
	create_asset(Name,Res),
	resource_description(Res,Key1),
	!,
	( 
	    Key0 = Key1 -> 
	    database_update(PkgDesc,WrongFields,ResKey)
	;
	    WrongFields = duplicated_name,
	    ResKey = none
	).
%	writeq(db_update(PkgDesc,WrongFields,ResKey)),nl.
db_update(PkgDesc0,WrongFields,ResKey):-
%	writeq('entering db_update'(PkgDesc0,WrongFields,ResKey)),nl,
	PkgDesc0 =.. [F,_Key0|Args],
	PkgDesc1 =.. [F,ResKey|Args], % _Key0 and ResKey are different!
	database_update(PkgDesc1,WrongFields,ResKey).
%	writeq(db_update(PkgDesc0,WrongFields,ResKey)),nl.

database_update(Desc,WrongFields,ResKey):-
	convert_arg_types(Desc,PkgDesc),
	PkgDesc = 'Software_Description_Validation'(ResKey,Name,Version,Size,
	  Description,IdentificationTags,Downloadpage,AuthorName,SubmittedbyName,
	  Contact,
	  License,NewVersionOf,Requires,Uses,LanguageName,Homepage,
	  Creationdate,Cost,_Certification,Security,MaintainerName,
	  Submissiondate,Licenseurl,References,Constraints,Freedom,
	  Environment,Signature),
%
	( 
	    resource_description(_Res,ResKey) -> 
	    resource_delete(ResKey)
	; 
	    true 
	),
	resource(Res),
        asset(Asset),
	resource_asset(Res,Asset,Res),
%
	(nonvar(LanguageName) ->
	 ditem(Language),
	 ditem_entry(Language,LanguageName,Language),
	 ditem_check(Language,WrongLanguage),
	 resource_language(Res,Language,Res)
	;
	    WrongLanguage = []
	),
%
	(nonvar(IdentificationTags),list(IdentificationTags) ->
	 gen_ditem_list(IdentificationTags,IdTags,WrongIdTags),
	 resource_identificationTags(Res,IdTags,Res)
	;
	    WrongIdTags = []
	),
%
	(nonvar(Requires),list(Requires) ->
	 gen_ditem_list(Requires,Reqs,WrongReqs),
	 resource_requires(Res,Reqs,Res)
	;
	    WrongReqs = []
	),
%
	resource_uses(Res,Uses,Res),
	resource_size(Res,Size,Res),
%
	resource_newVersionOf(Res,NewVersionOf,Res),
        resource_notes(Res,_Notes,Res),
%
	functor(PkgDesc,FName,FArity),
	functor(WrongFields,FName,FArity),
%
	organization(OrgAuthor),
	organization_name(OrgAuthor,AuthorName,OrgAuthor),
	organization_check(OrgAuthor,WrongOrgAuthor),
	user(Author),
	user_affiliation(Author,OrgAuthor,Author),
	user_check(Author,WrongAuthor),
%
	(nonvar(MaintainerName) ->
	 organization(OrgMaintainer),
	 organization_name(OrgMaintainer,MaintainerName,OrgMaintainer),
	 organization_check(OrgMaintainer,WrongOrgMaintainer),
	 user(Maintainer),
	 user_affiliation(Maintainer,OrgMaintainer,Maintainer),
	 user_check(Maintainer,WrongMaintainer),
	 asset_maintained_by(Asset,[Maintainer],Asset)
	;
	    WrongOrgMaintainer = [],
	    WrongMaintainer = []
	),
%
%%%  --- no certification is currently handled ---
%%% 	certification(Cert),
%%% 	certification_date(Cert,date,Cert),
%%% 	certification_status(Cert,status,Cert),
%%% 	certification_level(Cert,level,Cert),
%%% 	certification_policy(Cert,policy,Cert),
%%% 	certification_reference(Cert,reference,Cert),
%%% 	certification_artifact_type(Cert,artifact_type,Cert),
%%% 	certification_artifact(Cert,artifact,Cert),
%%% 	certification_verifier(Cert,verifier,Cert),
%%% 	certification_comments(Cert,comments,Cert),
%%% 	certification_check(Cert,WrongCert),
	WrongCert = [],  %% remove this line when certification is included.
%%%
%
	asset_name(Asset,Name,Asset),
	asset_author(Asset,[Author],Asset),
	asset_homepage(Asset,Homepage,Asset),
        asset_download_page(Asset,Downloadpage,Asset),
        asset_license(Asset,License,Asset),
        asset_license_URL(Asset,Licenseurl,Asset),
        asset_version(Asset,Version,Asset),
        asset_references(Asset,References,Asset),
        asset_additional_constraints(Asset,Constraints,Asset),
        asset_additional_freedom(Asset,Freedom,Asset),
        asset_description(Asset,Description,Asset),
        asset_creation_date(Asset,Creationdate,Asset),

	organization(OrgSubmittedby),
	organization_name(OrgSubmittedby,SubmittedbyName,OrgSubmittedby),
	organization_check(OrgSubmittedby,WrongOrgSubmittedby),
	user(Submittedby),
	user_affiliation(Submittedby,OrgSubmittedby,Submittedby),
	user_check(Submittedby,WrongSubmittedby),
	asset_submitted_by(Asset,Submittedby,Asset),
%
	asset_contact(Asset,Contact,Asset),
%
	asset_submission_date(Asset,Submissiondate,Asset),
        asset_environment(Asset,Environment,Asset),
        asset_cost(Asset,Cost,Asset),
        asset_security_classification(Asset,Security,Asset),
%%%
%%%        --- no certification is currently handled --- 
%%%     asset_certification(Asset,Cert,Asset),
%%%
        asset_package_signature(Asset,Signature,Asset),
	asset_check(Asset,WrongAsset),
%%%
%%%   --- no certification is currently handled ---
%%% 	resource_certification_status(Res,Cert_status,Res),
%%%
	resource_check(Res,WrongRes),
%
	ErrorList = [
			resource(WrongRes),
			author(WrongAuthor),
			orgauthor(WrongOrgAuthor),
			maintainer(WrongMaintainer),
			orgmaintainer(WrongOrgMaintainer),
			certification(WrongCert),
			idtags(WrongIdTags),
			reqs(WrongReqs),
			asset(WrongAsset),
			submit(WrongSubmittedby),
			orgsubmit(WrongOrgSubmittedby),
			lang(WrongLanguage)
		    ],
	!,
%	display(ErrorList), nl,
	(empty_lists(ErrorList) ->
	    resource_db_update(ResKey,Res)
	;
	    compose_errors_term(ErrorList,WrongFields),
	    display(WrongFields), nl,
	    ResKey = none
	).

create_asset(Name,Res):-
	resource(Res),
	asset(Asset),
	asset_name(Asset,Name,Asset),
	resource_asset(Res,Asset,Res),
	!.

controlled_ditem_db_update(Key, DItem, Message) :-
	ditem_generalization(DItem, G, DItem),
%	display(ditem_generalization(DItem, G, DItem)),nl,
	(gen_ok(G) ->
	 Message = ok
	;
	 Message = ko),
	ditem_db_update(Key, DItem).

gen_ok(G) :- 
	list(G), !,
	gen_ok_l(G).
gen_ok(G) :-
	it_is_ok(G).

gen_ok_l([]).
gen_ok_l([G|Gs]) :-
%	display(gen_ok(G)),nl,
	it_is_ok(G),
	gen_ok_l(Gs).

it_is_ok('$null$').
it_is_ok(G) :-
	ditem_description(G,_).

ditem_current_fact(LValues) :-
	build_ditem(LValues, null, DItem, _Entry, _Errs), 
 	ditem_description(DItem,_).

ditem_current_fact_entry(LValues) :-
	LValues = [Entry|Rest],
	length(Rest, N),
	length(EmptyList, N),
	build_ditem([Entry|EmptyList], null, DItem, _Entry, _Errs), 
 	ditem_description(DItem,_).
% 	ditem(DItem),
% 	LValues = [Entry|_],
% 	ditem_entry(DItem, Entry, NDItem),
% 	ditem_description(NDItem,_).
% %	build_ditem(LValues, DItem, _Entry, _Errs),
% %	ditem_exists(DItem).

:- pred build_ditem(+list, +atm, -ditem, -term, -error_list)

# "Given a list of atoms, produces the corresponding ditem and data
associated.".

build_ditem(LValues0, Flag, DItem, Entry, Errs) :-
	empty_to_var(LValues0, LValues),
	DI =..[di|LValues], 
	LValues = [Entry|_],
	gen_ditem(DI, DItem, E1),
	(Flag = null ->
	 ditem_check(DItem, E2)
	;
	 E2 = []
	),
	append(E1, E2, Errs).

empty_to_var([], []).
empty_to_var(['$empty'|Es], [_|Vs]) :- !,
	empty_to_var(Es, Vs).
empty_to_var([E|Es], [E|Vs]) :- !,
	empty_to_var(Es, Vs).

:- pred ditem_clone(+ditem, -ditem) 

# "Produces an empty ditem with the same entry as the input ditem.".

ditem_clone(DItem, DI) :-
	  ditem_entry(DItem, Entry, DItem),
	  ditem(DI),
	  ditem_entry(DI, Entry, DI).

:- pred ditems2terms(+ditem_list, +term, -term_list)

# "Given a list of ditems, produces the corresponding list of flatten WebDB
  predicates.".

ditems2terms([],_,[]).
ditems2terms([DI|DIs], Table, [P|Ps]) :-
	ditem_entry(DI, Entry, DI),
	ditem_generalization(DI, Gen, DI),
	ditem_definition(DI, Desc, DI),	
%	Desc = '',
	flatten(Gen, FGen),
	nil2void([Entry, Desc, FGen], Args),
	P =.. [Table|Args],
	ditems2terms(DIs, Table, Ps).

flatten('$null$', '').
flatten(Gen, FGen) :-
	flatten0(Gen, FGen0),
	flatten1(FGen0, FGen).

flatten0([], []).
flatten0([G|Gs], [FG|FGs]) :-
	ditem_entry(G, FG, G),
	flatten0(Gs, FGs).

flatten1([], '').
flatten1([F], F).
flatten1([F0|F0s], F) :-
	flatten1(F0s, Fs),
	atom_concat(F0, ' ', F1),
	atom_concat(F1, Fs, F).

nil2void([], []).
nil2void([[]|A0s], [''|As]) :- !,
	nil2void(A0s, As).
nil2void(['$null$'|A0s], [''|As]) :- !,
	nil2void(A0s, As).
nil2void([A|A0s], [A|As]) :-
	nil2void(A0s, As).

ditem_delete_all([]).
ditem_delete_all(L) :-
	\+ L = [],
	do_ditem_delete_all(L).

do_ditem_delete_all([]).
do_ditem_delete_all([DItem|Ds]) :-
	ditem_description(DItem, _),!,
	ditem_delete(DItem),
	do_ditem_delete_all(Ds).

:- pred gen_ditem(+term,-ditem,-error_list)

# "Given a term, produces the corresponding ditem and (possibly) a list of
  errors encountered in the process.".

gen_ditem(WebDBTerm, DItem, Errs) :- 
%	WebDBTerm = di(Entry, _Desc, Gens),
	WebDBTerm = di(Entry, Desc, Gens),
	process_generalizations(Gens, Generalizations, Errs), 
	ditem(DItem),
	ditem_entry(DItem, Entry, DItem),
	ditem_definition(DItem, Desc, DItem),
	ditem_generalization(DItem, Generalizations, DItem).
%	(ditem_description(DItem,_); true),
%	ditem_check(DItem, E2)

process_generalizations(V, V, []) :- var(V), !.
process_generalizations('$empty', _, []).
process_generalizations(Gens0, Gens, Errs) :-
	atom_codes(Gens0, CGens),
	split_into_atoms(CGens, AGenList),
	gen_ditem_list(AGenList, Gens, Errs).

split_into_atoms([], []).
split_into_atoms(" "||RestStr, RestAtoms):-
        !,
        split_into_atoms(RestStr, RestAtoms).
split_into_atoms(AtomStarts, [Atom|RestAtoms]):-
        AtomStarts \== [],
        first_atom(AtomStarts, String, RestString),
        atom_codes(Atom, String),
        split_into_atoms(RestString, RestAtoms).

first_atom("", "", "").
first_atom(" "||Xs, "", Xs):- !.
first_atom([X|Xs], [X|As], Ys):-
        first_atom(Xs, As, Ys).

:- pred gen_ditem_list(+list,-ditem_list,-error_list)

# "Given a list of atoms or strings, produces the list of ditems and
  (possibly) a list of errors encountered in the process.".

gen_ditem_list([],[],[]).
gen_ditem_list([A|As],[Ditem|Ditems],Errs):-
	to_lowercase(A,Alower),
	ditem(Ditem),
	ditem_entry(Ditem,Alower,Ditem),
	((ditem_description(Ditem, _), Err1 = []); ditem_check(Ditem,Err1)),
	gen_ditem_list(As,Ditems,Err2),
	append(Err1,Err2,Errs).

% Checks if the argument is a list of terms with empty lists as first arg.
empty_lists([]).
empty_lists([X|Xs]):-
	arg(1,X,[]),
	empty_lists(Xs).

:- pred compose_errors_term(ErrorList,WrongFields):
        list * term

# "fills in the @var{WrongFields} term the error messages of the wrong
  field lists given in @var{ErrorList}.
  Currently the only error message is the atom 'error'.".

compose_errors_term(ErrorList,WrongFields):-
	WrongFields =.. [_|Fields],
	field_correspondence(FieldNames),
	FieldNames =.. [_|Names],
	compose_error_list(ErrorList,Names,Fields),!.

compose_error_list([],_,_).
compose_error_list([Err|ErrList],Names,Fields):-
	functor(Err,Class,1),
	arg(1,Err,ErrFields),
	compose_error_list2(ErrFields,Class,Names,Fields),
	compose_error_list(ErrList,Names,Fields).

compose_error_list2([],_,_,_).
compose_error_list2([ErrField|ErrFields],Class,Names,Fields):-
	(nth(Pos,Names,Class:ErrField)
	;
	    nth(Pos,Names,List),member(Class:ErrField,List)
	),
	nth(Pos,Fields,'error'),
	compose_error_list2(ErrFields,Class,Names,Fields).
compose_error_list2([_|ErrFields],Class,Names,Fields):-
	% If a field is not found in web representation, this means that this 
	% error must not be reported.
	compose_error_list2(ErrFields,Class,Names,Fields).

:- pred convert_arg_types(+InTerm,-OutTerm)

# "Converts the types of every argument of @var{InTerm} to the
  appropriate type for the database, and puts the result in
  @var{OutTerm}.".

convert_arg_types(AtmTerm,TypeTerm):-
	functor(AtmTerm,F,A),
	functor(TypeTerm,F,A),
	AtmTerm =.. [_|AList],   % list of atoms.
	TypeTerm =.. [_|VList],  % list of fresh variables.
	field_types(Types),
	Types =.. [F|TList],     % list of types.
	convert_list_types(AList,TList,VList).
	
convert_list_types([],[],[]).
convert_list_types([Atm|Atms],[Type|Types],[Val|Vals]):-
	convert_type(Atm,Type,Val),
	convert_list_types(Atms,Types,Vals).

convert_type(Atm,_,Atm):-
	var(Atm),!.
convert_type(Atm,string,Val):- 
	int(Atm),!,
	number_codes(Atm,Val0),
	atom_codes(Val,Val0).   %%%IMPORTANT!!!! Strings represented as ATOMS!!!
convert_type(Atm,string,Val):- 
	number(Atm),!,
	number_codes(Atm,Val0),
	atom_codes(Val,Val0).   %%%IMPORTANT!!!! Strings represented as ATOMS!!!
convert_type([],string,'').
convert_type(Atm,string,Atm):- 
	atm(Atm),!.
%	atom_codes(Atm,Val).   %%%IMPORTANT!!!! Strings represented as ATOMS!!!
convert_type(Str,string,Val):-
	string(Str),
	!, atom_codes(Val,Str).   %%%IMPORTANT!!!! Strings represented as ATOMS!!!
convert_type(Atm,int,Atm):- 
	int(Atm),!.
convert_type(Atm,int,Val):-
	atm(Atm),
	atom_codes(Atm,SVal),
	number_codes(Val,SVal), !.
%jcfconvert_type(Atm,date,date(Day,Month,Year)):- !,
%jcf	% format 'YYYY/MM/DD', DD and MM may fit in 1 or 2 digits. 
%jcf	atm(Atm),
%jcf	atom_codes(Atm,Str),
%jcf	Str = [Y1,Y2,Y3,Y4,0'/|MD],
%jcf	number_codes(Year,[Y1,Y2,Y3,Y4]),
%jcf	(MD = [M,0'/|D] ->
%jcf	 number_codes(Month,[M]),
%jcf	 number_codes(Day,D)
%jcf        ;
%jcf	    MD = [M1,M2,0'/|D],
%jcf	    number_codes(Month,[M1,M2]),
%jcf	    number_codes(Day,D)
%jcf	 ).
convert_type(Atm,date,Val):- 
	atm(Atm),!,
%	atom_codes(Atm,Val),   %%%IMPORTANT!!!! Strings represented as ATOMS!!!
	Atm=Val,
	date(Val).
convert_type(Str,date,Val):- 
	string(Str), !,
	atom_codes(Val,Str),   %%%IMPORTANT!!!! Strings represented as ATOMS!!!
	date(Str).
convert_type([],list(_),[]).
convert_type([X|Xs],list(Type),[Y|Ys]):-
	convert_type(X,Type,Y),
	convert_type(Xs,list(Type),Ys).
convert_type(X,list(Type),[Y]):-
	\+ list(X),
	convert_type(X,Type,Y).
convert_type(Atm,_,Atm).

field_types('Software_Description_Validation'(
	atm,     %none:id
	string,  %asset:name,
	string,  %asset:version,
	int,     %resource:size,
	list(string),  %asset:description,
	list(string),  %resource:identification,
	string,  %asset:downloadpage,
	string,  %orgauthor:name,
	string,  %orgmaintainer:name,
	string,  %asset:contact,
	string,  %asset:license,
	string,  %resource:newVersionOf,
	list(string),  %resource:requires,
	list(string),  %resource:uses,
	string,  %resource:language,
	string,  %asset:homepage,
	date,    %asset:creationdate,
	string,  %asset:cost,
	string,  %none:certification, 
	string,  %asset:security,
	string,  %asset:submittedby,
	date,    %none:submissiondate,
	string,  %asset:licenseurl,
	string,  %asset:references,
	string,  %asset:constraints,
	string,  %asset:freedom,
	string,  %asset:environment,
	string   %asset:signature
	)).

field_correspondence('Software_Description_Validation'(
	none:id,              %not checked
	asset:name,
	asset:version,
	resource:size,
	asset:description,
	[idtags:entry,resource:identification], %two possible errors.
	asset:downloadpage,
	orgauthor:name,
	orgmaintainer:name,
	asset:contact,
	asset:license,
	resource:newVersionOf,
	[reqs:entry,resource:requires],
	[uses:entry,resource:uses],
	[lang:entry,resource:language],
	asset:homepage,
	asset:creationdate,
	asset:cost,
	none:certification,     %not checked
	asset:security,
%	asset:submittedby,
	orgsubmit:name,
%
	asset:submissiondate,
	asset:licenseurl,
	asset:references,
	asset:constraints,
	asset:freedom,
	asset:environment,
	asset:signature
	)).
%jcf%	none:id,                 % not checked.
%jcf%	asset:name,
%jcf%	asset:version,
%jcf%	resource:newVersionOf,
%jcf%	asset:description,
%jcf%	resource:size,
%jcf%	idtags:entry,
%jcf%	reqs:entry,
%jcf%	resource:uses,
%jcf%	resource:language,
%jcf%	asset:downloadpage,
%jcf%	asset:homepage,
%jcf%	asset:creationdate,
%jcf%	asset:cost,
%jcf%	none:certification,      % not checked.
%jcf%	asset:security,
%jcf%	orgauthor:name,
%jcf%	orgmaintainer:name,
%jcf%	orgsubmit:name,
%jcf%	orgcontact:name,
%jcf%	none:submissiondate,     % not checked???.
%jcf%	asset:license,
%jcf%	asset:licenseurl,
%jcf%	asset:references,
%jcf%	asset:constraints,
%jcf%	asset:freedom,
%jcf%	asset:environment,
%jcf%	asset:signature)).

:- pred db_resource_check(ResName):
        string

# "This predicate succeeds if @var{ResName} is the name of a resource
  in the database, and fails if such resource does not exist.".

db_resource_check(ResName):-
	resource(Res),
	asset(Asset),
	asset_name(Asset,ResName,Asset),
	resource_asset(Res,Asset,Res),
	resource_description(Res,_Key).


